from selenium.webdriver.common.by import By

from qturboframe.lib.webdriver.remote.webdriver import WebDriver
from qturboframe.lib.webdriver.remote.webelement import WebElement
from qturboframe.lib.webdriver.exceptions import SeleniumError
from qturboframe.lib.report.log import logger
from qturboframe.lib.utils.check import CheckBasic
from qturboframe.lib.utils.CustomError.custom_error import CustomError
from qturboframe.public_ui.base_element import BaseElement


class Radio(BaseElement, CheckBasic):
    """
    hui的单选按钮操作

    :Attributes:
     - elements: 单选按钮元素列表，list
    """

    def __init__(self, element_para, father=None, timeout=5):
        if isinstance(element_para, list) and len(element_para) > 0:
            if isinstance(element_para[0], WebElement):
                self._elements = element_para
                self._driver = element_para[0]._parent
                self.timeout = timeout
            else:
                message = 'element_para参数不正确，需是WebElement的集合！'
                raise SeleniumError(CustomError.Error_EQ03008001_Parameter_InCorrect, message)
        elif not isinstance(element_para, dict):
            message = 'element_para参数类型不正确！'
            raise SeleniumError(CustomError.Error_EQ03008001_Parameter_InCorrect, message)
        else:
            if father is None:
                message = '未定位元素，father参数不能为None！'
                raise SeleniumError(CustomError.Error_EQ03008001_Parameter_InCorrect, message)
            if isinstance(father, WebDriver):
                self._driver = father
                self.timeout = timeout
            elif isinstance(father, WebElement):
                self._driver = father._parent
                self.timeout = timeout
            else:
                raise AttributeError('father参数类型不正确！')
            key_list = [By.ID, By.NAME, By.CLASS_NAME, By.TAG_NAME, By.LINK_TEXT,
                        By.PARTIAL_LINK_TEXT,By.CSS_SELECTOR, By.XPATH]
            element_by = ''
            element_value = ''
            assist = ''
            for key, value in element_para.items():
                if key in key_list:
                    element_by = key
                    element_value = value
                else:
                    assist += '{}:{},'.format(key, value)
            assist = assist.strip(',')
            self._elements = father.find_elements_by_attribute(
                element_by, element_value, assist, self.timeout)

    @property
    def elements(self):
        '''
        获取单选按钮元素列表

        :Returns:
            返回单选按钮元素列表

        :Example:
         - 例: radio_element_list = radio.elements
        '''
        return self._elements

    def set_value(self, text):
        """
        hui的单选按钮控件选择

        :Args:
         - text: 选择项的文本

        :Example:
         - 例: radio.set_value('苹果')
        """
        for input_ele in self._elements:
            radio_label = input_ele.find_element_by_attribute(
                'xpath', './parent::span/parent::label', timeout=self.timeout)
            radio_text = radio_label.text
            if text == radio_text:
                try:
                    if input_ele.is_displayed():
                        input_ele.secure_click()
                    else:
                        radio_label.click()
                except Exception as e:
                    self._driver.execute_script("arguments[0].click();", radio_label)
                break

    def is_default(self, value):
        """
        检查hui单选按钮默认值

        :Args:
         - value: 待检查的选项值

        :Returns:
            匹配返回True，否则返回False

        :Example:
         - 例: radio.is_default('苹果')
        """
        for input_ele in self._elements:
            radio_label = input_ele.find_element_by_attribute(
                'xpath', './parent::span/parent::label', timeout=self.timeout)
            radio_class = radio_label.get_attribute('class')
            radio_text = radio_label.text
            if 'h-radio-wrapper-checked' in radio_class:
                if value == radio_text:
                    return True
        else:
            raise SeleniumError(CustomError.Error_EQ03010001_Verify_Expect_Actual_Not_Equal)

    def check_default(self, value):
        '''
        校验hui单选按钮默认值

        :Args:
         - value: 待检查的选项值

        :Raises:
            SeleniumError: 单选按钮的默认值检查不通过

        :Example:
         - 例: radio.check_default('苹果')
        '''
        if not self.is_default(value):
            message = '单选按钮的默认值检查不通过！'
            raise SeleniumError(CustomError.Error_EQ03015000_Radio_Default_Data_InCorrect, message)